package org.kong.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.kong.mapper.UserMapper;
import org.kong.pojo.dto.UserDTO;
import org.kong.pojo.dto.UserLoginDTO;
import org.kong.pojo.entity.User;
import org.kong.pojo.vo.UserVO;
import org.kong.service.UserService;
import org.kong.utils.JwtUtils;
import org.kong.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 加油
 *
 * @author konglingfeng
 * @date 2025/8/18
 * @desc
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private RedisUtil redisUtil;

    @Value("${token.expireTime}")
    private int expireTime;

    @Override
    public String login(UserLoginDTO userLoginDTO) {
        // 用户验证
        Authentication authentication = null;
        try {
            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager
                    .authenticate(new UsernamePasswordAuthenticationToken(userLoginDTO.getUsername(), userLoginDTO.getPassword()));
            log.info("用户认证成功：{}", authentication);
        } catch (Exception e) {
            if (e instanceof BadCredentialsException) {
                throw new RuntimeException("用户认证失败");
            } else {
                throw new RuntimeException(e.getMessage());
            }
        }
        // 生成jwt
        Map<String, Object> claims = new HashMap<>();
        claims.put("username", authentication.getName());
        // 获取权限对象，用于提取权限数据
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        Set<String> authoritySet = new HashSet<>();
        authorities.forEach(item -> authoritySet.add(item.getAuthority()));
        // 将权限数据放入claims,用于存入jwt
        claims.put("perms", authoritySet);

        // 将权限数据放入claims,用于存入jwt
        claims.put("perms", authoritySet);
        // 生成UUID
        String s = UUID.randomUUID().toString();
        String uuid = s.replace("-", "");
        // uuid存储到jwt的token中一份
        claims.put("uuid",uuid);
        // 创建token
        String token = jwtUtils.createJwt(claims);
        // 利用uuid当做键,将token存储到redis
        redisUtil.setCacheObject("user:key:"+uuid,token,expireTime, TimeUnit.SECONDS);

        return token;
    }

    @Override
    public List<UserVO> list(UserDTO userDTO) {
        return userMapper.list(userDTO);
    }

    @Override
    public boolean delete(Integer id) {
        return userMapper.delete(id);
    }

    @Override
    public boolean deleteBatch(List<Integer> ids) {
        return userMapper.deleteBatch(ids);
    }

    @Override
    public boolean add(User user) {
        user.setCreateTime(new Date());
        //密码加密
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        user.setPassword(encoder.encode(user.getPassword()));
        log.info("添加用户：{}", user);
        return userMapper.add(user);
    }

    @Override
    public boolean update(User user) {
        if (user.getPassword() != null) {
            //密码加密
            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
            user.setPassword(encoder.encode(user.getPassword()));
        }
        return userMapper.update(user);
    }
}
